﻿using Abp.Application.Services.Dto;
using Abp.Authorization;
using Abp.AutoMapper;
using Abp.Domain.Repositories;
using Abp.Linq.Extensions;
using Abp.Runtime.Session;
using Abp.UI;
using Microsoft.AspNet.Identity;
using SingleUserMall.Authorization.Users;
using SingleUserMall.Common;
using SingleUserMall.Items;
using SingleUserMall.Stores.Form;
using SingleUserMall.Stores.VO;
using System;
using System.Linq;
using System.Threading.Tasks;

namespace SingleUserMall.Stores
{
    [AbpAuthorize]
    public class StoreManageAppService : SingleUserMallAppServiceBase, IStoreManageAppService
    {
        private readonly IRepository<Store> _storeRepository;

        private readonly IRepository<User, long> _userRepository;
        private readonly IRepository<BusinessScope, long> _businessScopeRepository;
        public StoreManageAppService(IRepository<Store> storeRepository, IRepository<User, long> userRepository, IRepository<BusinessScope, long> businessScopeRepository)
        {
            _storeRepository = storeRepository;

            _userRepository = userRepository;

            _businessScopeRepository = businessScopeRepository;
        }
        public async Task<StoreVO> GetStoreAsync(SingleId<int> form)
        {
            var store = await _storeRepository.FirstOrDefaultAsync(form.Id);
            return store.ToVO<Store, StoreVO>((v, vo) =>
            {
                vo.InBusinessScope = _businessScopeRepository.FirstOrDefault(x => x.Id == v.BusinessScopeId);
            });
        }


        public async Task<StoreVO> GetStoreByUserId()
        {
            var userId = AbpSession.GetUserId();
            var store = await _storeRepository.FirstOrDefaultAsync(x => x.UserId == userId);
            return store.ToVO<Store, StoreVO>((v, vo) =>
            {
                vo.InBusinessScope = _businessScopeRepository.FirstOrDefault(x => x.Id == v.BusinessScopeId);
            });
        }

        public async Task<PagedResultDto<StoreVO>> GetStoresBySearchAsync(StoreSearchForm form)
        {
            var userId = AbpSession.GetUserId();
            var query = _storeRepository.GetAll().Where(x => x.Status == StoreVerifyStatus.Audited)
                .WhereIf(!string.IsNullOrEmpty(form.Keywords), x => x.Name.Contains(form.Keywords) || x.Discription.Contains(form.Keywords))
                .OrderByDescending(x => x.CreationTime);
            return await query.ToPagedResultDtoAsync<Store, StoreVO>(form, (v, vo) =>
            {
                vo.InBusinessScope = _businessScopeRepository.FirstOrDefault(x => x.Id == v.BusinessScopeId);
            });
        }

        public async Task<PagedResultDto<StoreVO>> GetVerifyStoresByAsync(StoreVerifyPagedForm form)
        {
            var query = _storeRepository.GetAll()
                .WhereIf(form.Status.HasValue, x => x.Status == form.Status)
                .WhereIf(!string.IsNullOrEmpty(form.Keywords), x => x.Name.Contains(form.Keywords) || x.Discription.Contains(form.Keywords))
                .OrderByDescending(x => x.CreationTime);
            return await query.ToPagedResultDtoAsync<Store, StoreVO>(form, (v, vo) =>
            {
                vo.InBusinessScope = _businessScopeRepository.FirstOrDefault(x => x.Id == v.BusinessScopeId);
            });
        }

        public async Task VerifyStoresAsync(StoreAuditForm form)
        {
            var store = await _storeRepository.FirstOrDefaultAsync(form.Id);
            store.Status = form.IsPass ? StoreVerifyStatus.Audited : StoreVerifyStatus.Rejected;
            store.StoreStar = 5;
            store.StoreTotalSale = 500;
            var newAdminuser = new User();
            if (form.IsPass)
            {
                newAdminuser.Surname = store.Name;
                newAdminuser.UserName = store.Name;
                newAdminuser.Name = store.Name;
                newAdminuser.IsAdmin = true;
                newAdminuser.EmailAddress = $"{newAdminuser.UserName}@singleusermall.com";
                newAdminuser.Password = new PasswordHasher().HashPassword(User.DefaultPassword);
                newAdminuser.IsActive = true;
                var tempUserid = await _userRepository.InsertAndGetIdAsync(newAdminuser);
                await CurrentUnitOfWork.SaveChangesAsync();
                var user = await UserManager.GetUserByIdAsync(tempUserid);
                await UserManager.AddToRolesAsync(user.Id, new string[] { "商城管理员" });
                var olduser = await UserManager.GetUserByIdAsync(store.UserId);
                store.UserId = user.Id;
            }
        }

        public async Task<ListResultDto<StoreVO>> GetStoresAsync()
        {
            var userId = AbpSession.GetUserId();
            var query = _storeRepository.GetAll().Where(x => x.Status == StoreVerifyStatus.Audited);
            return await query.ToListResultDtoAsync<Store, StoreVO>((v, vo) =>
            {
                vo.InBusinessScope = _businessScopeRepository.FirstOrDefault(x => x.Id == v.BusinessScopeId);
            });
        }

        public async Task SaveStoreAsync(StoreForm form)
        {
            var store = await _storeRepository.FirstOrDefaultAsync(form.Id);
            if (store != null)
            {
                store = form.MapTo(store);
                await _storeRepository.UpdateAsync(store);
            }
            else
            {
                store = form.MapTo<Store>();
                store.AuthType = "无";
                store.UserId = 1;
                store.Status = StoreVerifyStatus.Audited;
                await _storeRepository.InsertAsync(store);
            }
        }


        public async Task SetStoreBanlanceAsync(StoreBanlanceForm form)
        {
            var store = await _storeRepository.FirstOrDefaultAsync(form.Id);
            if (store != null)
            {
                if (store.UnBanlancedSaleAmount < form.BanlancedSaleAmount)
                {
                    throw new UserFriendlyException("结算金额大于未结算金额，不能结算");
                }
                store.BanlancedSaleAmount += form.BanlancedSaleAmount;
                store.UnBanlancedSaleAmount -= form.BanlancedSaleAmount;
                await _storeRepository.UpdateAsync(store);
            }
        }
    }
}
